﻿using Acb.Core.Data;
using Acb.Core.Exceptions;
using Acb.Core.Extensions;
using Acb.Dapper;
using Acb.Dapper.Domain;
using Dapper;
using OAuth.Server.Domain.Entities;
using System;
using System.Threading.Tasks;

namespace OAuth.Server.Domain
{
    public class AccountRepository : DapperRepository<TAccount>
    {
        public async Task<TAccount> Login(string account, string password)
        {
            var user = await QueryByAccountAsync(account);
            if (user == null)
                throw new BusiException("帐号不存在");
            if (!string.Equals(user.Password, $"{password}{user.PasswordSalt}".Md5(),
                StringComparison.CurrentCultureIgnoreCase))
                throw new BusiException("登录密码错误");
            return user;
        }

        public async Task<TAccount> QueryByAccountAsync(string account)
        {
            var type = typeof(TAccount);
            SQL sql = $"SELECT {type.Columns()} FROM [{type.PropName()}] WHERE [{nameof(TAccount.Account)}]=@account";
            //手机号码认证
            sql += $"OR (([{nameof(TAccount.AuthStates)}] & 1) > 0 AND [{nameof(TAccount.Mobile)}]=@account)";
            //邮箱认证
            sql += $"OR (([{nameof(TAccount.AuthStates)}] & 2) > 0 AND [{nameof(TAccount.Email)}]=@account)";
            var t = Connection.FormatSql(sql.ToString());
            return await Connection.QueryFirstOrDefaultAsync<TAccount>(t, new { account });
        }

        /// <summary> 添加登录日志 </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> InsertLoginAsync(TAccountLogin model)
        {
            return await Connection.InsertAsync(model, trans: Trans);
        }

        /// <summary> 添加平台信息 </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> InsertPlatformAsync(TAccountPlatform model)
        {
            return await Connection.InsertAsync(model, trans: Trans);
        }

        /// <summary> 更新平台信息 </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<int> UpdatePlatformAsync(TAccountPlatform model)
        {
            return await Connection.UpdateAsync(model, new[]
            {
                nameof(TAccountPlatform.AccessToken),
                nameof(TAccountPlatform.RefreshToken),
                nameof(TAccountPlatform.Nick),
                nameof(TAccountPlatform.Avatar),
                nameof(TAccountPlatform.LoginTime),
                nameof(TAccountPlatform.ExpiredTime)
            }, Trans);
        }
    }
}
